<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head></head>
<body>
<h1>Configuring a NFS-GANESHA server as a NFS proxy</h1>
<br>
NFS-GANESHA
has different beckoned modules, each of them dedicated to address a
specific namespace. These bookends are called FSAL (which stands for
"File System Abstraction Layer"). One of these FSAL, the FSAL_PROXY, is
in fact a NFSv4 client whose API is compliant with the FSAL API. Used
with NFS-GANESHA, it turns the NFSv4 server into a NFSv4 proxy.<br>
<br>
The configuration should be done like this:<br>
<br>
<h2>Step 1: Compiling NFS-GANESHA with the FSAL_PROXY</h2>
This is very simple, just proceed as follow:<br>
<div style="margin-left: 40px;"># ./configure
--with-fsal=PROXY<br>
# make<br>
# make install<br>
</div>
<br>
This will produce the binaries <span style="font-style: italic;">proxy.ganesha.nfsd</span>
and <span style="font-style: italic;">proxy.ganeshell</span>.
<br>
<br>
<h2>Step 2 : Writing the configuration file.</h2>
Suppose you have a NFSv4 server running on host named <span style="font-style: italic;">alpha</span>, which
exports <span style="font-style: italic;">/home</span>
via NFSv4. You want to make the NFS-GANESHA server running on a
secondary machine named <span style="font-style: italic;">beta</span>.<br>
<br>
First of all, make sure that you have regular NFSv4 access to the <span style="font-style: italic;">alpha</span> machine from <span style="font-style: italic;">beta</span> for <span style="font-style: italic;">/home</span><br>
<div style="margin-left: 40px;">beta# mount -t nfs4
alpha:/home /mnt</div>
<br>
Make sure that you have root access from beta to alpha from the mount
point.<br>
<br>
Then
you can write the configuration file. As for any other NFS-GANESHA's
configuration step, you have a dedicated block, entitled NFSv4_Proxy to
be written:<br>
<br>
This is a simple example:<br>
<div style="margin-left: 40px;">NFSv4_Proxy<br>
{<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Srv_Addr = alpha.mydomain ;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
NFS_Port =&nbsp;&nbsp;&nbsp; 2049 ;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
NFS_Service = 100003 ;<br>
<br>
#WARNING /!\&nbsp; Small NFS_SendSize and NFS_RecvSize may lead to
problems <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
NFS_SendSize = 32768 ;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
NFS_RecvSize = 32768 ;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Retry_SleepTime = 60 ;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NFS_Proto
= "tcp" ;<br>
}</div>
<br>
The fields have the following meanings:<br><ul><li><span style="font-style: italic;">Srv_Addr</span>: the name or the IP address (in dotted notation) of the server to be accessed by the proxy</li><li><span style="font-style: italic;">NFS_Port</span> and <span style="font-style: italic;">NFS_Service</span>:
can be used to specify alternate value to the classical port=2049,
service=100003. This fields are used for debugging purpose mostly, you
can omit them</li><li><span style="font-style: italic;">NFS_SendSize</span>, <span style="font-style: italic;">NFS_RecvSize</span>:
they are used to specify the size to be used for RPC packets. I
strongly suggest not to use small packets, 32KB is commonly a very good
value.</li><li><span style="font-style: italic;">NFS_Proto</span>:
determines if UDP or TCP are to be used for accessing the server to be
proxyfied. Because the proxy is using NFSv4 connection, TCP is a far
better choice than udp</li></ul>The field Path in the Export block is important
too: it tells the path you want to access via the proxy. It is
equivalent to the path after the name of the server in the classical
mount command<br>So if you do this command to mount server alpha on host beta :<br><div style="margin-left: 40px;">mount -t nfs4 alpha:<span style="font-weight: bold; text-decoration: underline;">/home</span> /mnt</div>You should have this in you configuration file:<br><div style="margin-left: 40px;">Export<br>{<br>&nbsp; &nbsp; &nbsp; # Exported path (mandatory)<br>&nbsp; Path = "/home" ;<br>.<br>.<br>.<br>}</div><br><h2>Let's have an actual example</h2>I want to access by proxy the /home on host alpha. I'll be using this basic configuration file:<br><div style="margin-left: 40px;"><br>EXPORT<br>{<br>&nbsp; Export_Id = 1 ;<br>&nbsp; <br>&nbsp; Path = "/home" ;<br>&nbsp;<br>&nbsp; Root_Access = "*" ;<br>&nbsp; <br>&nbsp; Pseudo = "/proxy/alpha/home_alpha";<br>&nbsp; <br>&nbsp; Access_Type = RW;<br>&nbsp; <br>&nbsp; Anonymous_root_uid = -2 ;<br>&nbsp;&nbsp; <br>&nbsp; Cache_Data = FALSE ;<br>&nbsp; <br>}<br><br>###################################################<br>#<br># Configuration of the NFSv4 proxy<br>#<br>###################################################<br>NFSv4_Proxy<br>{<br>&nbsp;&nbsp;&nbsp; Srv_Addr = alpha;<br><br>#WARNING /!\&nbsp; Small NFS_SendSize and NFS_RecvSize may lead to problems <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NFS_SendSize = 32768 ;<br>&nbsp;&nbsp;&nbsp; NFS_RecvSize = 32768 ;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Retry_SleepTime = 60 ;<br>&nbsp;&nbsp;&nbsp; NFS_Proto = "tcp" ;<br>}</div><br>Now, from a NFSv4 client machine, I can do this (note the impact of the NFSv4 path using pseudofs) :<br><div style="margin-left: 40px;">mount -t nfs4 beta:/proxy/alpha/home_alpha /mnt</div><br>You'll have access to alpha:/home through this mount point.<br><br><h2>Re-exporting in NFSv3 from the proxy.</h2>The
proxy server can re-export in NFSv3. This could be pretty useful:
imagine a cluster of local machine wanting to access a remote server,
on another site (through a WAN for example). The proxy server will be
the only one to make NFSv4 access to this remote server (which
simplifies a lot firewall configuration) and then re-export the
namespace it access through NFSv3 on the local cluster, serving lots of
clients in a stateless way.<br><br>For enabling this feature, you will need SQLite 3.0 to be installed on your machine and configure NFS-GANESHA that way:<br><div style="margin-left: 40px;"># ./configure --with-fsal=PROXY --enable-handle-mapping</div><br>This will had a small SQLite engine to the proxy. This DB will store association between remote files and NFSv3 file handle.<br>A few additional tags are required in the NFSv4_Proxy blocks, in order to configure this DB engine:<br><div style="margin-left: 40px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>NFSv4_Proxy<br>{<br>&nbsp;&nbsp;&nbsp; Srv_Addr = alpha;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;NFS_SendSize = 32768 ;<br>&nbsp;&nbsp;&nbsp; NFS_RecvSize = 32768 ;<br>&nbsp;&nbsp;&nbsp;&nbsp;Retry_SleepTime = 60 ;<br>&nbsp;&nbsp;&nbsp; NFS_Proto = "tcp" ;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-weight: bold;">Enable_Handle_Mapping = TRUE;</span><br style="font-weight: bold;"><span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;HandleMap_DB_Dir&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = "/var/nfs-ganesha/handledbdir/";</span><br style="font-weight: bold;"><span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;HandleMap_Tmp_Dir&nbsp;&nbsp;&nbsp;&nbsp; = "/tmp";</span><br style="font-weight: bold;"><span style="font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;HandleMap_DB_Count&nbsp;&nbsp;&nbsp; = 8;</span><br>}</div><br>These parameters have the following meaning:<br><ul><li><span style="font-style: italic;">Enable_Handle_Mapping</span> : activates the feature of Handle Mapping that is used there</li><li><span style="font-style: italic;">HandleMap_DB_Dir</span> : the path were SQLite will store its data files</li><li><span style="font-style: italic;">HandleMap_Tmp_Dir</span>: temporary directory required by SQLite</li><li><span style="font-style: italic;">HandleMap_DB_Count</span>:
the number of different maps to be used. Each maps is managed by a
dedicated thread, this number also indicates a number of threads
spawned as the service starts up.</li></ul><br>With the previous example, on a non NFSv4 client, you can now do this:<br><div style="margin-left: 40px;">mount -o vers=3,udp beta:/home&nbsp; /mnt</div><br>Through mount point /mnt, you&nbsp;now have access to /home on alpha, via the proxy on beta.<br><br><h2>Using RPCSEC_GSS with FSAL_PROXY</h2>You need to activate the use of libgssrpc (RPCSEC_GSS implementation provided with MIT krb5)<br><div style="margin-left: 40px;">#&nbsp; ./configure --enable-gssrpc&nbsp;&nbsp; --with-fsal=PROXY</div><br>Then, you have to use the following additional parameters:<br><ul><li><span style="font-style: italic;">Active_krb5</span>: must be set to TRUE</li><li><span style="font-style: italic;">Local_PrincipalName</span>: nfs local principal name, should be something like nfs@beta</li><li><span style="font-style: italic;">Remote_PrincipalName</span>: nfs principal for remote server, should be something like nfs@alpha</li><li><span style="font-style: italic;">KeytabPath</span>: path to the keytab to be used for acquiring cred for&nbsp;Local_PrincipalName</li><li><span style="font-style: italic;">Credential_LifeTime</span>: the time before refreshing credentials</li><li><span style="font-style: italic;">Sec_Type</span>: type of security, possible value are krb5, krb5i, krb5p. The meaning is the same as for the "-osec=" option of mount.</li></ul>Example of configuration file <br><div style="margin-left: 40px;">NFSv4_Proxy<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Srv_Addr = alpha ;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # RPCSEC_GSS/krb5 specific items<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Active_krb5 = TRUE ;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Principal used by FSAL_PROXY<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Local_PrincipalName = nfs@beta.mydomain ;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # NFS Principal on remote NFS Server <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Remote_PrincipalName = nfs@alpha.mydomain ;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Ketab were key for local principal resides<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; KeytabPath = /etc/krb5.keytab ;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Lifetime for acquired credentials<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Credential_LifeTime = 86400 ;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Security Type should be krb5,krb5i or krb5p<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Sec_Type = krb5p ;<br>}<br><br></div></body></html>
